﻿
//表达式转化器

namespace n_PyExpression
{
using System;
using n_PyConfig;
using n_PyConstString;
using n_PyCPUType;
using n_PyDeploy;
using n_PyET;
using n_PyFunctionList;
using n_PyMemberType;
using n_PyOperation;
using n_PyParse;
using n_PyParseNet;
using n_PyStructList;
using n_PyUnitList;
using n_PyVarList;
using n_PyVarNode;
using n_PyVarType;
using n_PyVdataList;
using n_PyWordList;
using n_PyCallList;
using n_PyByteCode;
using n_PyFuncMap;

public static class Expression
{
	static bool isLeft;
	static bool isComp;
	static int isSimpleSet;
	static bool InterVar;
	
	//如果返回 -1,表示解析表达式出现错误,而返回 void 类型时通过 GetType 去判断
	public static string 表达式( int Index )
	{
		++Deploy.ExpLevel;
		
		string Name = null;
		string Head = ParseNet.NodeSet[ Index ][ 0 ];
		switch( Head ) {
			case ParseNet.Node.括号运算:		Name = 括号运算( Index ); break;
			case ParseNet.Node.双目运算符:	Name = 双目运算( Index ); break;
			case ParseNet.Node.单目运算:		Name = 单目运算( Index ); break;
			case ParseNet.Node.函数调用:		Name = 函数调用( Index ); break;
			case ParseNet.Node.变量:			Name = 变量( Index ); break;
			case ParseNet.Node.列表定义:		Name = 列表定义( Index ); break;
			case ParseNet.Node.表达式:		Name = 表达式( int.Parse( ParseNet.NodeSet[ Index ][ 1 ] ) ); break;
			//case ParseNet.Node.终结词:		Name = 终结词( Index ); break;
			default:
				ET.WriteParseError( Index, "<Expression.cs表达式> 未定义的运算项: " + Head );
				break;
		}
		return Name;
	}
	
	static string 括号运算( int Index )
	{
		Deploy.SetCLine( ParseNet.NodeSet[ Index ][ 1 ] );
		//++Deploy.ExpLevel;
		return 表达式( int.Parse( ParseNet.NodeSet[ Index ][ 2 ] ) );
	}
	
	static string 双目运算( int Index )
	{
		string r = "";
		
		++Deploy.ExpLevel;
		
		Deploy.SetCLine( ParseNet.NodeSet[ Index ][ 2 ] );
		
		//获取运算符号
		int OperIndex = int.Parse( ParseNet.NodeSet[ Index ][ 2 ] );
		string Oper = WordList.GetWord( OperIndex );
		
		//判断是否为赋值运算
		if( Oper == "=" ) {
			
			Deploy.SetValue = true;
			
			InterVar = false;
			
			//先按照简单赋值语句分析, 不成立再重新按照复合量赋值语句分析
			int firsti = int.Parse( ParseNet.NodeSet[ Index ][ 3 ] );
			r = 表达式( firsti );
			
			isSimpleSet = 0;
			
			isLeft = true;
			r += 表达式( int.Parse( ParseNet.NodeSet[ Index ][ 1 ] ) );
			isLeft = false;
			
			if( isSimpleSet == 0 || InterVar ) {
				return r;
			}
			Deploy.SetValue = false;
			
			//这里按照复合变量赋值分析
			isLeft = true;
			r = 表达式( int.Parse( ParseNet.NodeSet[ Index ][ 1 ] ) );
			isLeft = false;
			
			firsti = int.Parse( ParseNet.NodeSet[ Index ][ 3 ] );
			r += 表达式( firsti );
			
			if( isSimpleSet == 1 ) {
				r += PyByteCode.STORE_DOT + "\n";
			}
			if( isSimpleSet == 2 ) {
				r += PyByteCode.CALL_FUNCTION + " 3\n";
			}
			return r;
		}
		//到这里说明是普通双目运算
		isComp = false;
		bool CMP = false;
		switch( Oper ) {
				case "+":	Oper = PyInnerFunc.__add__; break;
				case "-":	Oper = PyInnerFunc.__sub__; break;
				case "**":	Oper = PyInnerFunc.__power__; break;
				case "*":	Oper = PyInnerFunc.__mul__; break;
				case "/":	Oper = PyInnerFunc.__div__; break;
				case "//":	Oper = PyInnerFunc.__d_div__; break;
				case "%":	Oper = PyInnerFunc.__mod__; break;
				case "+=":	Oper = PyInnerFunc.__inp_add__; isComp = true; break;
				case "-=":	Oper = PyInnerFunc.__inp_sub__; isComp = true; break;
				case "**=":	Oper = PyInnerFunc.__inp_power__; isComp = true; break;
				case "*=":	Oper = PyInnerFunc.__inp_mul__; isComp = true; break;
				case "/=":	Oper = PyInnerFunc.__inp_div__; isComp = true; break;
				case "//=":	Oper = PyInnerFunc.__inp_d_div__; isComp = true; break;
				case "%=":	Oper = PyInnerFunc.__inp_mod__; isComp = true; break;
				case "<":	Oper = PyInnerFunc.__cmp_s__; break;
				case "<=":	Oper = PyInnerFunc.__cmp_se__; break;
				case "==":	Oper = PyInnerFunc.__cmp_e__; break;
				case "!=":	Oper = PyInnerFunc.__cmp_ne__; break;
				case ">":	Oper = PyInnerFunc.__cmp_l__; break;
				case ">=":	Oper = PyInnerFunc.__cmp_le__; break;
				default:	break;
		}
		CMP = isComp;
		
		//到这里说明是普通二元运算
		r += 表达式( int.Parse( ParseNet.NodeSet[ Index ][ 1 ] ) );
		
		isComp = false;
		
		r += SetClassFunc( Oper );
		
		r += 表达式( int.Parse( ParseNet.NodeSet[ Index ][ 3 ] ) );
		
		//传递函数索引用于后期处理
		//int fi = n_PyFunctionList.FunctionList.GetIndex( FunctionName );
		//return r + PyByteCode.CALL_FUNCTION + " " + (fi * 256 + RealVarNumber) + "\n";
		
		r += PyByteCode.CALL_FUNCTION + " 2\n";
		if( CMP ) {
			Deploy.SetValue = true;
			return r += PyByteCode.POP_TOP + "\n";
		}
		return r;
	}
	
	static string 单目运算( int Index )
	{
		string r = "";
		
		++Deploy.ExpLevel;
		
		Deploy.SetCLine( ParseNet.NodeSet[ Index ][ 1 ] );
		
		//获取运算符
		int OperIndex = int.Parse( ParseNet.NodeSet[ Index ][ 1 ] );
		string Oper;
		if( ParseNet.NodeSet[ OperIndex ][ 0 ] == ParseNet.Node.前括号运算 ) {
			int OperTypeIndex = int.Parse( ParseNet.NodeSet[ OperIndex ][ 2 ] );
			if( ParseNet.NodeSet[ OperTypeIndex ][ 0 ] == ParseNet.Node.基本变量类型 ) {
				string OperType = Parse.GetType( Deploy.UnitName, OperTypeIndex );
				if( OperType == null ) {
					return null;
				}
				Oper = "(" +  OperType + ")";
			}
			else {
				Oper = "(" + WordList.GetWord( OperTypeIndex ) + ")";
			}
		}
		else {
			Oper = WordList.GetWord( OperIndex );
		}
		//解析右操作数
		r += 表达式( int.Parse( ParseNet.NodeSet[ Index ][ 2 ] ) );
		
		switch( Oper ) {
			case "-":	Oper = PyInnerFunc.__neg__; break;
			default:	break;
		}
		
		r += SetClassFunc( Oper );
		
		//传递函数索引用于后期处理
		//int fi = n_PyFunctionList.FunctionList.GetIndex( FunctionName );
		//return r + PyByteCode.CALL_FUNCTION + " " + (fi * 256 + RealVarNumber) + "\n";
		return r + PyByteCode.CALL_FUNCTION + " 1\n";
	}
	
	static string 变量( int Index )
	{
		++Deploy.ExpLevel;
		
		string r = "";
		
		int AIndex = int.Parse( ParseNet.NodeSet[ Index ][ 1 ] );
		int FirstIndex = int.Parse( ParseNet.NodeSet[ Index ][ 2 ] );
		int NextIndex = int.Parse( ParseNet.NodeSet[ Index ][ 3 ] );
		string[] Cut = ParseNet.NodeSet[ NextIndex ];
		int CurrentIndex = 1;
		
		//迭代处理元件嵌套引用
		string NextUnitName = null;
		string FirstNameWord = WordList.GetWord( FirstIndex );
		
		if( AIndex != -1 ) {
			NextUnitName = VarType.Root + "." + FirstNameWord;
		}
		else {
			NextUnitName = Deploy.UnitName + "." + FirstNameWord;
		}
		
		if( UnitList.GetIndex( NextUnitName ) != -1 ) {
			string UnitName = NextUnitName;
			return "未知: 元件名";
		}
		else {
			
			Deploy.SetCLine( ParseNet.NodeSet[ Index ][ 2 ] );
			
			InterVar = false;
			bool isEnd = Cut.Length == 1;
			
			if( FirstNameWord + "." == Config.linkboy_ui ) {
				int ParseIndex = int.Parse( Cut[ 1 ] );
				
				FirstIndex = int.Parse( ParseNet.NodeSet[ ParseIndex ][ 2 ] );
				InterVar = true;
				
				isEnd = Cut.Length == 2;
			}
			r = 终结词( InterVar, isEnd, FirstIndex, AIndex );
		}
		if( InterVar ) {
			return r;
		}
		
		//迭代处理后缀
		for( int i = CurrentIndex; i < Cut.Length; ++i ) {
			
			int ParseIndex = int.Parse( Cut[ i ] );
			
			//如果需要改回统一的点运算,包括数组下标运算,只需要去掉else语句,并且在 <分量运算> 中使能下标
			if( ParseNet.NodeSet[ ParseIndex ][ 0 ] == ParseNet.Node.点运算 ) {
				r += 附点分量运算( i == Cut.Length - 1, ParseIndex );
			}
			else {
				r += 数组分量运算( i == Cut.Length - 1, ParseIndex );
			}
		}
		return r;
	}
	
	static string 列表定义( int Index )
	{
		string r = "";
		
		++Deploy.ExpLevel;
		
		Deploy.SetCLine( ParseNet.NodeSet[ Index ][ 1 ] );
		
		//获取表达式序列
		int OperIndex = int.Parse( ParseNet.NodeSet[ Index ][ 2 ] );
		int VarNumber = 0;
		if( OperIndex != -1 ) {
			for( int i = 1; i < ParseNet.NodeSet[OperIndex].Length; i += 2 ) {
				//解析第 i 个表达式
				int PointOper = int.Parse( ParseNet.NodeSet[OperIndex][ i ] );
				r += 表达式( PointOper );
				VarNumber++;
			}
		}
		r += PyByteCode.BUILD_LIST + " " + VarNumber + "\n";
		
		return r;
	}
	
	static string 附点分量运算( bool isEnd, int Index )
	{
		string r = null;
		if( isEnd && isLeft ) {
			isSimpleSet = 1;
		}
		bool lft = isLeft;
		isLeft = false;
		string Name = WordList.GetWord( int.Parse( ParseNet.NodeSet[ Index ][ 2 ] ) );
		
		//这里根据name计算出对应的属性名称ID
		int Number = 34;
		r += PyByteCode.LOAD_CONST + " " + Number + "\n";
		
		isLeft = lft;
		
		if( isEnd && isLeft ) {
			//r += PyByteCode.CALL_FUNCTION + " 3\n";
		}
		else {
			r += PyByteCode.LOAD_DOT + "\n";
		}
		return r;
	}
	
	static string 数组分量运算( bool isEnd, int Index )
	{
		string r = null;
		if( isEnd && isLeft ) {
			//调用 __setitem__ 函数
			r = Expression.SetClassFunc( PyInnerFunc.__setitem__ );
			isSimpleSet = 2;
		}
		else {
			//调用 __getitem__ 函数
			r = Expression.SetClassFunc( PyInnerFunc.__getitem__ );
		}
		bool lft = isLeft;
		isLeft = false;
		r += 表达式( int.Parse( ParseNet.NodeSet[ Index ][ 2 ] ) );
		isLeft = lft;
		if( isEnd && isLeft ) {
			//r += PyByteCode.CALL_FUNCTION + " 3\n";
		}
		else {
			r += PyByteCode.CALL_FUNCTION + " 2\n";
		}
		return r;
	}
	
	static string 终结词( bool isInterVar, bool isEnd, int Index, int AIndex )
	{
		++Deploy.ExpLevel;
		
		string Name = WordList.GetWord( Index );
		
		//判断字符常量或数字
		if( ConstString.isValue( Name ) ) {
			string Type = null;
			string Number = ConstString.GetValue( ref Type, Name, Index );
			
			if( Type == VarType.BaseType.Bool ) {
				return PyByteCode.LOAD_BOOL + " " + Number + "\n";
			}
			else {
				long d = long.Parse( Number );
				if( d >= 65536 ) {
					return
						PyByteCode.LOAD_CONST32 + " " + (d % 65536) + "\n" +
						PyByteCode.LOAD_CONST32 + " " + (d / 65536) + "\n";
				}
				else {
					return PyByteCode.LOAD_CONST + " " + Number + "\n";
				}
			}
		}
		//判断是否为字符串
		else if( Name.StartsWith( "\"" ) ) {
			int Size = 0;
			int CodeType = 0;
			string Result = StringCoder.GetCode( Name, ref Size, ref CodeType, Index );
			
			string name = n_PyUserString.PyUserString.Add( Result );
			
			return PyByteCode.LOAD_STRING + " " + Size + "\n" +
				   PyByteCode.LOAD_STRING + " #addrw0+" + name + "\n";
		}
		else {
			int VarAddr = 0;
			
			//这里暂时未考虑 isEnd
			
			if( isLeft && isEnd ) {
				
				if( isInterVar ) {
					return PyByteCode.STORE_GLOBAL_C + " #addr+" + Name + "\n";
				}
				else {
					
					//判断是否为局部变量
					if( VarList.CanDefineLocal( Deploy.FunctionIndex, Name ) ) {
						
						//判断是否为全局变量
						if( VarList.CanDefineStatic( Name ) ) {
							
							//添加变量
							VarNode v = new VarNode( Name, Deploy.AddMain?-1:Deploy.FunctionIndex, Index, Deploy.AddMain );
							int i = VarList.Add( v );
							VarAddr = v.Addr;
							if( Deploy.AddMain ) {
								return PyByteCode.STORE_GLOBAL + " " + VarAddr + "\n";
							}
							else {
								return PyByteCode.STORE_FAST + " " + VarAddr + "\n";
							}
						}
						else {
							
							//这里需要检查一下权限, 之前是否用 global 导入了相关的全局变量名字
							
							int i = VarList.GetStaticIndex( Name );
							VarAddr = VarList.Get( i ).Addr;
							return PyByteCode.STORE_GLOBAL + " " + VarAddr + "\n";
						}
					}
					else {
						int i = VarList.GetLocalIndex( Deploy.FunctionIndex, Name );
						VarAddr = VarList.Get( i ).Addr;
						return PyByteCode.STORE_FAST + " " + VarAddr + "\n";
					}
				}
			}
			else {
				
				if( !isInterVar ) {
					int i = VarList.GetLocalIndex( Deploy.FunctionIndex, Name );
					if( i == -1 ) {
						i = VarList.GetStaticIndex( Name );
						if( i == -1 ) {
							ET.WriteParseError( Index, "变量尚未初始化:" + Name );
							return "null";
						}
						VarAddr = VarList.Get( i ).Addr;
					}
					else {
						VarAddr = VarList.Get( i ).Addr;
					}
					if( isComp ) {
						if( VarList.Get( i ).Static ) {
							return PyByteCode.LOAD_GLOBAL_CMP + " " + VarAddr + "\n";
						}
						else {
							return PyByteCode.LOAD_FAST_CMP + " " + VarAddr + "\n";
						}
					}
					else {
						if( VarList.Get( i ).Static ) {
							return PyByteCode.LOAD_GLOBAL + " " + VarAddr + "\n";
						}
						else {
							return PyByteCode.LOAD_FAST + " " + VarAddr + "\n";
						}
					}
				}
				else {
					return PyByteCode.LOAD_GLOBAL_C + " #addr+" + Name + "\n";
				}
			}
		}
	}
	
	static string 函数调用( int Index )
	{
		++Deploy.ExpLevel;
		
		string r = "";
		
		Deploy.SetCLine( ParseNet.NodeSet[ Index ][ 2 ] );
		
		//获取函数名
		int FunctionNameIndex = int.Parse( ParseNet.NodeSet[ Index ][ 1 ] );
		string FunctionName = null;
		int ErrorIndex = -1;
		Parse.GetMemberNames( Deploy.UnitName, FunctionNameIndex, ref FunctionName, ref ErrorIndex );
		
		bool isNewObj = false;
		
		string ssFunctionName = null;
		if( FunctionName.StartsWith( Deploy.UnitName + "." + Config.linkboy_ui ) || FunctionName.StartsWith( Deploy.UnitName + "." + Config.linkboy_py ) ) {
			ssFunctionName = FunctionName.Remove( 0, Deploy.UnitName.Length + 1 );
		}
		else {
			
			//如果ssFunctionName是一个类, 那么表明是调用构造函数, 需要加上 __init__
			if( UnitList.isExist( FunctionName ) ) {
				FunctionName += "." + PyInnerFunc.__init__;
				isNewObj = true;
			}
			
			ssFunctionName = FunctionName.Remove( 0, 2 );
		}
		
		bool InterFuncCall = false;
		bool InterFuncCallPy = false;
		bool ClassFunc = false;
		int iv = -1;
		
		if( ssFunctionName.StartsWith( Config.linkboy_ui ) ) {
			InterFuncCall = true;
			InterFuncCallPy = false;
			ssFunctionName = ssFunctionName.Remove( 0, Config.linkboy_ui.Length );
			r += PyByteCode.LOAD_CONST + " #addr+" + ssFunctionName + "\n";
		}
		else if( ssFunctionName.StartsWith( Config.linkboy_py ) ) {
			InterFuncCall = true;
			InterFuncCallPy = true;
			ssFunctionName = ssFunctionName.Remove( 0, Config.linkboy_py.Length );
			r += PyByteCode.LOAD_CONST + " #addr+" + ssFunctionName + "\n";
		}
		else {
			
			iv = VarList.GetStaticIndex( ssFunctionName );
			if( iv == -1 ) {
				
				//判断是对象函数调用还是用户自定义函数调用
				int DotIndex = ssFunctionName.IndexOf( "." );
				if( DotIndex != -1 ) {
					string InnerFunc = ssFunctionName.Remove( 0, DotIndex + 1 );
					ssFunctionName = ssFunctionName.Remove( DotIndex );
					
					iv = VarList.GetStaticIndex( ssFunctionName );
					if( iv == -1 ) {
						ET.WriteParseError( FunctionNameIndex, "未定义的变量:" + ssFunctionName );
						return null;
					}
					
					//这里可以提前判断一下是否存在 InnerFunc 这个名字的成员函数
					//...
					
					//读取对象地址并压栈 注意: 这里稍后会替换为函数对象的地址
					r += PyByteCode.LOAD_GLOBAL + " " + VarList.Get( iv ).Addr + "\n";
					
					//这里是核心, 根据栈顶的对象类型, 动态查找方法并压栈替换
					
					r += SetClassFunc( InnerFunc );
					
					ClassFunc = true;
				}
				else {
					ET.WriteParseError( FunctionNameIndex, "未定义的函数:" + ssFunctionName );
					return null;
				}
			}
			else {
				r += PyByteCode.LOAD_GLOBAL + " " + VarList.Get( iv ).Addr + "\n";
			}
		}
		
		//获取实参列表
		int RealVarListIndex = int.Parse( ParseNet.NodeSet[ Index ][ 3 ] );
		
		//形参尺寸变量归零
		int RealVarNumber = 0;
		
		//如果是对象构造函数调用, 需要额外增加一个self参数
		if( isNewObj ) {
			RealVarNumber++;
			r += PyByteCode.LOAD_NONE + "\n";
		}
		
		if( RealVarListIndex != -1 ) {
			
			string[] RealVarList = ParseNet.NodeSet[ RealVarListIndex ];
			
			//实参变量列表
			
			//迭代解析实参列表,注意如果改回原先的函数调用方式,需要修改下边的 i - 1 这个表达式,
			//一共要改3个地方,上面还有一段代码也涉及到 除2 或 减1 (RealVarLength)
			for( int i = 1; i < RealVarList.Length; i += 2 ) {
				
				//解析第 i 个实参
				int PointOper = int.Parse( RealVarList[ i ] );
				string j = 表达式( PointOper );
				
				r += j;
				RealVarNumber++;
			}
		}
		if(  ClassFunc ) {
			
			//读取对象地址并压栈 (这里是调用底层对象方法时传递的对象引用参数) 正常传参
			//r += PyByteCode.LOAD_GLOBAL + " " + VarList.Get( iv ).Addr + "\n";
			
			//不再替换 而是新增函数地址 之前的对象还在栈空间, 所以不需要重新压栈参数了
			
			RealVarNumber++;
		}
		
		if( InterFuncCall ) {
			if( InterFuncCallPy ) {
				return r + PyByteCode.CALL_FUNCTION_PY + " " + (RealVarNumber) + "\n";
			}
			else {
				return r + PyByteCode.CALL_FUNCTION_C + " " + (RealVarNumber) + "\n";
			}
		}
		else {
			//传递函数索引用于后期处理
			//int fi = n_PyFunctionList.FunctionList.GetIndex( FunctionName );
			//return r + PyByteCode.CALL_FUNCTION + " " + (fi * 256 + RealVarNumber) + "\n";
			return r + PyByteCode.CALL_FUNCTION + " " + (RealVarNumber) + "\n";
		}
	}
	
	public static string SetClassFunc( string funcname )
	{
		//这里是核心, 根据栈顶的对象类型, 动态查找方法并压栈 (然后交换栈顶顺序)
		//r += PyByteCode.CALL_FUNCTION_I + " " + InnerFunc + "\n";
		int FuncID = n_PyByteCode.PyInnerFunc.GetFuncIndex( funcname );
		if( FuncID == -1 ) {
			ET.WriteParseError( 0, "<SetClassFunc>未定义的函数:" + funcname );
		}
		return PyByteCode.GET_CLASS_FUNCTION + " " + FuncID + "\n";
	}
	
	public static string SetClassFuncSave( string funcname )
	{
		//这里是核心, 根据栈顶的对象类型, 动态查找方法并压栈 (然后交换栈顶顺序)
		//r += PyByteCode.CALL_FUNCTION_I + " " + InnerFunc + "\n";
		int FuncID = n_PyByteCode.PyInnerFunc.GetFuncIndex( funcname );
		if( FuncID == -1 ) {
			ET.WriteParseError( 0, "<SetClassFuncSave>未定义的函数:" + funcname );
		}
		return PyByteCode.GET_CLASS_FUNCTION_SAVE + " " + FuncID + "\n";
	}
}
}



